package com.geccocrawler.socks5.handler.ss5;

import com.geccocrawler.socks5.ProxyServer;
import com.geccocrawler.socks5.auth.PropertiesPasswordAuth;
import com.geccocrawler.socks5.auth.PropertiesWhiteListAuth;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.socksx.SocksVersion;
import io.netty.handler.codec.socksx.v5.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;

public class Socks5InitialRequestHandler extends SimpleChannelInboundHandler<DefaultSocks5InitialRequest> {
    private static final Logger logger = LoggerFactory.getLogger(Socks5InitialRequestHandler.class);
    private ProxyServer proxyServer;
    static private PropertiesWhiteListAuth whiteListAuth;

    static {
        whiteListAuth = new PropertiesWhiteListAuth();
    }

    public Socks5InitialRequestHandler(ProxyServer proxyServer) {
        this.proxyServer = proxyServer;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DefaultSocks5InitialRequest msg) throws Exception {
        logger.debug("初始化ss5连接 : " + msg);
        if (msg.decoderResult().isFailure()) {
            logger.debug("不是ss5协议");
            ctx.fireChannelRead(msg);
        } else {
            InetSocketAddress ipSocketAddress = (InetSocketAddress) ctx.channel().remoteAddress();
            if (msg.version().equals(SocksVersion.SOCKS5)) {
                if (proxyServer.isAuth() && !whiteListAuth.auth(ipSocketAddress.getAddress().getHostAddress())) {
                    //socks auth
                    ctx.channel().pipeline().addAfter("Socks5InitialRequestHandler", "Socks5PasswordAuthRequestDecoder", new Socks5PasswordAuthRequestDecoder());
                    ctx.channel().pipeline().addAfter("Socks5PasswordAuthRequestDecoder", "Socks5PasswordAuthRequestHandler", new Socks5PasswordAuthRequestHandler());

                    Socks5InitialResponse initialResponse = new DefaultSocks5InitialResponse(Socks5AuthMethod.PASSWORD);
                    ctx.writeAndFlush(initialResponse);
                } else {
                    logger.debug("当前IP不需要身份验证!!!");
                    Socks5InitialResponse initialResponse = new DefaultSocks5InitialResponse(Socks5AuthMethod.NO_AUTH);
                    ctx.writeAndFlush(initialResponse);
                }
            }
        }
    }

}
